#include "stdafx.h"
#include "Intersection.h"

Intersection::Intersection():t(MAXFLOAT)
{
	obj = NULL;
}

Intersection::Intersection(Point pt, Couleur c, Vecteur normale1, float t1)
{
	pt.normalize();

	p = pt;
	couleur = c;
	normale = normale1;
	t = t1;
	obj = NULL;
}

Intersection::Intersection(Intersection const& inter)
{
	p = inter.p;
	couleur = inter.couleur;
	normale = inter.normale;
	t = inter.t;
	obj = inter.obj;
}

Intersection::~Intersection(){}

Intersection& Intersection::operator=(Intersection const& inter)
{
	p = inter.p;
	couleur = inter.couleur;
	normale = inter.normale;
	t = inter.t;
	obj = inter.obj;

	return *this;
}

Point Intersection::getPoint()
{
	return p;
}

Couleur Intersection::getCouleur()
{
	return couleur;
}

Vecteur Intersection::getNormale()
{
	return normale;
}

float Intersection::getT()
{
	return t;
}

Objet* Intersection::getObjet()
{
	return obj;
}

void Intersection::setPoint(Point p1)
{
	p1.normalize();
	p = p1;
}

void Intersection::setNormale(Vecteur v)
{
	v.normalisation();
	normale = v;
}

void Intersection::setCouleur(Couleur c)
{
	couleur = c;
}

void Intersection::setT(float t1)
{
	t = t1;
}

void Intersection::setObjet(Objet* objet)
{
	obj = objet;
}

Rayon Intersection::calculRayonRef(Vecteur rayonDir, Objet* obj)
{
	Vecteur normale1 = normale;

	if(obj->getProprietes().getBump())
		normale1 = obj->getProprietes().getNormale(*this);

	rayonDir.normalize();

	rayonDir.inverse();

	float scal = normale1.produitScalaire(rayonDir);
	if(scal<0)
	{
		normale1.inverse();
		scal = -scal;
	}

	Vecteur rayonRefDir;
	rayonRefDir.setX( 2*scal*normale1.getX() - rayonDir.getX()  );
	rayonRefDir.setY( 2*scal*normale1.getY() - rayonDir.getY()  );
	rayonRefDir.setZ( 2*scal*normale1.getZ() - rayonDir.getZ()  );

	rayonRefDir.normalize();

	return Rayon(p, rayonRefDir);
}

Rayon Intersection::calculRayonTrans( Vecteur rayonDir, float nRefracAvant, Objet* obj )
{
	float nRefracApres = obj->getProprietes().getCoffRefractive();

	if(nRefracAvant == nRefracApres)
		return Rayon(p, rayonDir,nRefracApres);

	Vecteur normale1 = normale;

	if(obj->getProprietes().getBump())
		normale1 = obj->getProprietes().getNormale(*this);
	
	normale1.normalize();
	rayonDir.normalize();

	float angleA = -normale1.produitScalaire(rayonDir); //cosa
	if(angleA<0)
	{
		normale1.inverse();
		angleA = -angleA;
	}

	float n = nRefracAvant / nRefracApres;

	float angleB2 = 1.0f - n*n*(1.0f-angleA*angleA);

	if(angleB2 <0)
	{
		return Rayon(p, rayonDir,nRefracApres);
	}

	float angleB = sqrt(angleB2);//cosb
	float temp = n*angleA-angleB;

	Vecteur T;

	T.setX(rayonDir.getX()*n - temp*normale1.getX());
	T.setY(rayonDir.getY()*n - temp*normale1.getY());
	T.setZ(rayonDir.getZ()*n - temp*normale1.getZ());

	T.normalize();
	return Rayon(p, T,nRefracApres);
}

Rayon Intersection::calculRayonGlossy(Vecteur rayonDir, float random, Objet* obj)
{
	Vecteur normale1 = normale;
	if(obj->getProprietes().getBump())
		normale1 = obj->getProprietes().getNormale(*this);

	normale1.normalize();
	rayonDir.normalize();

	rayonDir.inverse();

	float scal = normale1.produitScalaire(rayonDir);
	if(scal<0)
	{
		normale1.inverse();
		scal = -scal;
	}

	Vecteur rayonGlossyDir;
	rayonGlossyDir.setX( 2*scal*normale1.getX() - rayonDir.getX() + random);
	rayonGlossyDir.setY( 2*scal*normale1.getY() - rayonDir.getY()  + random);
	rayonGlossyDir.setZ( 2*scal*normale1.getZ() - rayonDir.getZ()  + random);

	rayonGlossyDir.normalize();

	return Rayon(p, rayonGlossyDir);
}





